home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / language / embedded / mcu / asembler.arc / DO11.C < prev    next >
Text File  |  1987-12-09  |  6KB  |  278 lines

  1. /*
  2.  *      MC68HC11 specific processing
  3.  */
  4.  
  5. #define PAGE1   0x00
  6. #define PAGE2   0x18
  7. #define PAGE3   0x1A
  8. #define PAGE4   0xCD
  9.  
  10. /* addressing modes */
  11. #define IMMED   0
  12. #define INDX    1
  13. #define INDY    2
  14. #define LIMMED  3       /* long immediate */
  15. #define OTHER   4
  16.  
  17. int     yflag = 0;      /* YNOIMM, YLIMM, and CPD flag */
  18.  
  19. /*
  20.  *      localinit --- machine specific initialization
  21.  */
  22. localinit()
  23. {
  24. }
  25.  
  26. /*
  27.  *      do_op --- process mnemonic
  28.  *
  29.  *    Called with the base opcode and it's class. Optr points to
  30.  *    the beginning of the operand field.
  31.  */
  32. do_op(opcode,class)
  33. int opcode;    /* base opcode */
  34. int class;    /* mnemonic class */
  35. {
  36.     int     dist;   /* relative branch distance */
  37.     int     amode;  /* indicated addressing mode */
  38.     char    *peek;
  39.  
  40.     /* guess at addressing mode */
  41.     peek = Optr;
  42.     amode = OTHER;
  43.     while( !delim(*peek) && *peek != EOS)  /* check for comma in operand field */
  44.         if( *peek++ == ',' ){
  45.             if( mapdn(*peek) == 'y' )
  46.                 amode = INDY;
  47.             else
  48.                 amode = INDX;
  49.             break;
  50.             }
  51.     if( *Optr == '#' ) amode = IMMED;
  52.  
  53.     yflag = 0;
  54.     switch(class){
  55.         case P2INH:
  56.             emit(PAGE2);
  57.         case INH:                       /* inherent addressing */
  58.             emit(opcode);
  59.             return;
  60.         case REL:                       /* relative branches */
  61.             eval();
  62.             dist = Result - (Pc+2);
  63.             emit(opcode);
  64.             if( (dist >127 || dist <-128) && Pass==2){
  65.                 error("Branch out of Range");
  66.                 emit(lobyte(-2));
  67.                 return;
  68.                 }
  69.             emit(lobyte(dist));
  70.             return;
  71.         case LONGIMM:
  72.             if( amode == IMMED )
  73.                 amode = LIMMED;
  74.         case NOIMM:
  75.             if( amode == IMMED ){
  76.                 error("Immediate Addressing Illegal");
  77.                 return;
  78.                 }
  79.         case GEN:                       /* general addressing */
  80.             do_gen(opcode,amode,PAGE1,PAGE1,PAGE2);
  81.             return;
  82.         case GRP2:
  83.             if( amode == INDY ){
  84.                 Cycles++;
  85.                 emit(PAGE2);
  86.                 amode = INDX;
  87.                 }
  88.             if( amode == INDX )
  89.                 do_indexed(opcode);
  90.             else{   /* extended addressing */
  91.                 eval();
  92.                 emit(opcode+0x10);
  93.                 eword(Result);
  94.                 }
  95.             return;
  96.         case CPD:               /* cmpd */
  97.             if( amode == IMMED )
  98.                 amode = LIMMED;
  99.             if( amode == INDY )
  100.                 yflag=1;
  101.             do_gen(opcode,amode,PAGE3,PAGE3,PAGE4);
  102.             return;
  103.         case XNOIMM:            /* stx */
  104.             if( amode == IMMED ){
  105.                 error("Immediate Addressing Illegal");
  106.                 return;
  107.                 }
  108.         case XLIMM:             /* cpx, ldx */
  109.             if( amode == IMMED )
  110.                 amode = LIMMED;
  111.             do_gen(opcode,amode,PAGE1,PAGE1,PAGE4);
  112.             return;
  113.         case YNOIMM:            /* sty */
  114.             if( amode == IMMED ){
  115.                 error("Immediate Addressing Illegal");
  116.                 return;
  117.                 }
  118.         case YLIMM:             /* cpy, ldy */
  119.             if(amode == INDY)
  120.                 yflag=1;
  121.             if( amode == IMMED )
  122.                 amode = LIMMED;
  123.             do_gen(opcode,amode,PAGE2,PAGE3,PAGE2);
  124.             return;
  125.         case BTB:               /* bset, bclr */
  126.         case SETCLR:            /* brset, brclr */
  127.             opcode = bitop(opcode,amode,class);
  128.  
  129.             if (amode == INDX)
  130.                 Cycles++;
  131.             if( amode == INDY ){
  132.                 Cycles+=2;
  133.                 emit(PAGE2);
  134.                 amode = INDX;
  135.                 }
  136.             emit(opcode);
  137.             eval();
  138.             emit(lobyte(Result));   /* address */
  139.             if( amode == INDX )
  140.                 Optr += 2;      /* skip ,x or ,y */
  141.             Optr = skip_white(Optr);
  142.             eval();
  143.             emit(lobyte(Result));   /* mask */
  144.             if( class == SETCLR )
  145.                 return;
  146.             Optr = skip_white(Optr);
  147.             eval();
  148.             dist = Result - (Pc+1);
  149.             if( (dist >127 || dist <-128) && Pass==2){
  150.                 error("Branch out of Range");
  151.                 dist = Old_pc - (Pc+1);
  152.                 }
  153.             emit(lobyte(dist));
  154.             return;
  155.         default:
  156.             fatal("Error in Mnemonic table");
  157.         }
  158. }
  159.  
  160. /*
  161.  *      bitop --- adjust opcode on bit manipulation instructions
  162.  */
  163. bitop(op,mode,class)
  164. int op;
  165. int mode;
  166. int class;
  167. {
  168.     if( mode == INDX || mode == INDY )
  169.         return(op);
  170.     if( class == SETCLR )
  171.         return(op-8);
  172.     else if(class==BTB)
  173.         return(op-12);
  174.     else
  175.         fatal("bitop");
  176. }
  177.  
  178. /*
  179.  *      do_gen --- process general addressing modes
  180.  */
  181. do_gen(op,mode,pnorm,px,py)
  182. int     op;     /* base opcode */
  183. int     mode;   /* addressing mode */
  184. int     pnorm;  /* page for normal addressing modes: IMM,DIR,EXT */
  185. int     px;     /* page for INDX addressing */
  186. int     py;     /* page for INDY addressing */
  187. {
  188.     switch(mode){
  189.     case LIMMED:
  190.         Optr++;
  191.         epage(pnorm);
  192.         emit(op);
  193.         eval();
  194.         eword(Result);
  195.         break;
  196.     case IMMED:
  197.         Optr++;
  198.         epage(pnorm);
  199.         emit(op);
  200.         eval();
  201.         emit(lobyte(Result));
  202.         break;
  203.     case INDY:
  204.         if(yflag)
  205.             Cycles += 2;
  206.         else
  207.             Cycles += 3;
  208.         epage(py);
  209.         do_indexed(op+0x20);
  210.         break;
  211.     case INDX:
  212.         Cycles+=2;
  213.         epage(px);
  214.         do_indexed(op+0x20);
  215.         break;
  216.     case OTHER:
  217.         eval();
  218.         epage(pnorm);
  219.         if(Force_word){
  220.             emit(op+0x30);
  221.             eword(Result);
  222.             Cycles+=2;
  223.             break;
  224.             }
  225.         if(Force_byte){
  226.             emit(op+0x10);
  227.             emit(lobyte(Result));
  228.             Cycles++;
  229.             break;
  230.             }
  231.         if(Result>=0 && Result <=0xFF){
  232.             emit(op+0x10);
  233.             emit(lobyte(Result));
  234.             Cycles++;
  235.             break;
  236.             }
  237.         else {
  238.             emit(op+0x30);
  239.             eword(Result);
  240.             Cycles+=2;
  241.             break;
  242.             }
  243.         break;
  244.     default:
  245.         error("Unknown Addressing Mode");
  246.     }
  247. }
  248.  
  249. /*
  250.  *      do_indexed --- handle all wierd stuff for indexed addressing
  251.  */
  252. do_indexed(op)
  253. int op;
  254. {
  255.     char c;
  256.  
  257.     emit(op);
  258.     eval();
  259.     if( *Optr++ != ',' )
  260.         error("Syntax");
  261.     c = mapdn(*Optr++);
  262.     if( c != 'x' && c != 'y')
  263.         warn("Indexed Addressing Assumed");
  264.     if( Result < 0 || Result > 255)
  265.         warn("Value Truncated");
  266.     emit(lobyte(Result));
  267. }
  268.  
  269. /*
  270.  *      epage --- emit page prebyte
  271.  */
  272. epage(p)
  273. int p;
  274. {
  275.     if( p != PAGE1 )        /* PAGE1 means no prebyte */
  276.         emit(p);
  277. }
  278.